package com.scau402.system1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.scau402.common.exception.ServiceException;
import com.scau402.common.utils.SecurityUtils;
import com.scau402.common.utils.StringUtils;
import com.scau402.system.domain.WmsInboundOrder;
import com.scau402.system1.domain.vo.WmsWareStorageVO;
import com.scau402.system1.mapper.WmsWarehouseMapper;
import com.scau402.system1.domain.dto.WmsWarehouseDTO;
import com.scau402.system1.domain.po.WmsWarehouseDO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 仓库Service接口
 *
 * @author ruoyi
 * @date 2023-06-26
 */
@Service
public class WmsWarehouseService {

    @Resource
    private WmsWarehouseMapper wmsWarehouseMapper;

    public void add(WmsWarehouseDO wmsWarehouseDO) {
        // 编码是否重复
        WmsWarehouseDO one = wmsWarehouseMapper.selectOne(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getWarehouseCode, wmsWarehouseDO.getWarehouseCode())
                        .eq(WmsWarehouseDO::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                        .eq(WmsWarehouseDO::getDelFlag, "0")
        );
        if (one != null) {
            throw new ServiceException("仓库编码已存在");
        }

        // 检查仓库名称是否已经存在
        one = wmsWarehouseMapper.selectOne(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getWarehouseName, wmsWarehouseDO.getWarehouseName())
                        .eq(WmsWarehouseDO::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                        .eq(WmsWarehouseDO::getDelFlag, "0")
        );
        if (one != null) {
            throw new ServiceException("仓库名称已存在");
        }

        wmsWarehouseDO.setId(null);
        if (wmsWarehouseDO.getMaxCap() == null) {
            wmsWarehouseDO.setMaxCap(-1L);
        }
        wmsWarehouseDO.setUsedCap(0L);
        wmsWarehouseDO.setDelFlag("0");

        wmsWarehouseDO.setTenantId(SecurityUtils.getLoginUser().getTenantId());

        wmsWarehouseDO.setCreateBy(SecurityUtils.getLoginUser().getUsername());
        wmsWarehouseDO.setCreateTime(new Date());

        wmsWarehouseDO.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
        wmsWarehouseDO.setUpdateTime(new Date());

        doIfSetDefault(wmsWarehouseDO);
        wmsWarehouseMapper.insert(wmsWarehouseDO);
    }

    public void deleteById(Long id) {
        WmsWarehouseDO wmsWarehouseDO = wmsWarehouseMapper.selectOne(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, id)
                        .eq(WmsWarehouseDO::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                        .eq(WmsWarehouseDO::getDelFlag, "0")
        );
        if (wmsWarehouseDO == null) {
            throw new ServiceException("删除的仓库不存在");
        }
        if (wmsWarehouseDO.getUsedCap() != 0L) {
            throw new ServiceException("当前仓库还存有货物，无法删除");
        }
        wmsWarehouseMapper.update(
                null,
                new LambdaUpdateWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, id)
                        .set(WmsWarehouseDO::getDelFlag, "2")
        );
    }

    public List<WmsWarehouseDO> list(WmsWarehouseDTO wmsWarehouseDTO) {
        return wmsWarehouseMapper.selectList(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getDelFlag, "0")
                        .eq(WmsWarehouseDO::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                        .like(
                                StringUtils.isNotEmpty(wmsWarehouseDTO.getWarehouseCode()),
                                WmsWarehouseDO::getWarehouseCode,
                                wmsWarehouseDTO.getWarehouseCode()
                        )
                        .like(
                                StringUtils.isNotEmpty(wmsWarehouseDTO.getWarehouseName()),
                                WmsWarehouseDO::getWarehouseName,
                                wmsWarehouseDTO.getWarehouseName()
                        )
                        .eq(
                                StringUtils.isNotEmpty(wmsWarehouseDTO.getStatus()),
                                WmsWarehouseDO::getStatus,
                                wmsWarehouseDTO.getStatus()
                        )
                        .orderByDesc(WmsWarehouseDO::getCreateTime)
        );
    }

    /**
     * 查询仓库
     *
     * @param id 仓库主键
     * @return 仓库, 不查询已删除的
     */
    public WmsWarehouseDO selectWmsWarehouseById(Long id) {
        return wmsWarehouseMapper.selectOne(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, id)
                        .eq(WmsWarehouseDO::getDelFlag, "0")
        );
    }

    /**
     * 修改仓库
     *
     * @param wmsWarehouseDO 仓库
     */
    public void updateWmsWarehouse(WmsWarehouseDO wmsWarehouseDO) {
        if (wmsWarehouseDO.getMaxCap() == null) {
            wmsWarehouseDO.setMaxCap(-1L);
        }

        WmsWarehouseDO origin = selectWmsWarehouseById(wmsWarehouseDO.getId());
        if (!Objects.equals(origin.getMaxCap(), wmsWarehouseDO.getMaxCap())) {
            if (wmsWarehouseDO.getMaxCap() != -1L && wmsWarehouseDO.getMaxCap() < origin.getUsedCap()) {
                throw new ServiceException("当前设置的最大容量小于已使用的容量");
            }
        }
        doIfSetDefault(wmsWarehouseDO);
        wmsWarehouseMapper.update(
                wmsWarehouseDO,
                new LambdaUpdateWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, wmsWarehouseDO.getId())
                        .eq(WmsWarehouseDO::getTenantId, SecurityUtils.getLoginUser().getTenantId())
        );
    }

    private void doIfSetDefault(WmsWarehouseDO wmsWarehouseDO) {
        if ("1".equals(wmsWarehouseDO.getIsDefault())) {
            wmsWarehouseMapper.update(
                    null,
                    new LambdaUpdateWrapper<WmsWarehouseDO>()
                            .eq(WmsWarehouseDO::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                            .eq(WmsWarehouseDO::getDelFlag, "0")
                            .set(WmsWarehouseDO::getIsDefault, "0")
            );
        }
    }

    public boolean checkInOK(Long id) {
        WmsWarehouseDO wmsWarehouseDO = wmsWarehouseMapper.selectOne(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, id)
                        .eq(WmsWarehouseDO::getDelFlag, "0")
        );
        String status = wmsWarehouseDO.getStatus();
        return !"2".equals(status) && !"3".equals(status);
    }

    @Deprecated
    public boolean checkFull(Long id) {
        //根据id查询仓库信息
        WmsWarehouseDO wmsWarehouseDO = wmsWarehouseMapper.selectOne(
                new LambdaQueryWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, id)
                        .eq(WmsWarehouseDO::getDelFlag, "0")
        );
        //判断最大容量是否为-1
        if (wmsWarehouseDO.getMaxCap() == -1) {
            return false;
        }
        //最大容量小于等于已使用个数表示已满
        return wmsWarehouseDO.getMaxCap() <= wmsWarehouseDO.getUsedCap();
    }

    /**
     * 检查仓库是否还有足够的空位
     * @param wmsWarehouseDO 仓库信息实体类
     * @return 结果
     */
    public boolean checkFull(WmsWarehouseDO wmsWarehouseDO){
//        //判断最大容量是否为-1
//        if (wmsWarehouseDO.getMaxCap() == -1) {
//            return false;
//        }
//        return wmsWarehouseDO.getMaxCap() <= wmsWarehouseDO.getUsedCap();
        return wmsWarehouseDO.getMaxCap()==-1 ? false : wmsWarehouseDO.getMaxCap()<=wmsWarehouseDO.getUsedCap();
    }

    public void updateQuantity(WmsInboundOrder wmsInboundOrder) {
        // TODO  2023/12/29 15:56: 暂时通过
        //throw new UnsupportedOperationException(
        //        "是不是一个在修改仓库容量的时候再同步更新仓库容量，而且具体的容量计算逻辑应该由调用方计算才对"
        //);
    }

    /**
     * 增加仓位后即将仓位所申请的空间视为仓库已使用的空间，如是入库占用空间，请使用仓位中的函数
     */
    public void increaseUsedCap(long warehouseId, long cap) {
        WmsWarehouseDO wmsWarehouseDO = selectWmsWarehouseById(warehouseId);
        if (wmsWarehouseDO.getMaxCap() != -1 && cap == -1) {
            throw new ServiceException("设置为无限容量,但所属仓库不是无限容量");
        }

        if (wmsWarehouseDO.getMaxCap() == -1 && cap == -1) {
            return;
        }

        if (wmsWarehouseDO.getMaxCap() == -1 && cap != -1) {
            wmsWarehouseMapper.update(
                    null,
                    new LambdaUpdateWrapper<WmsWarehouseDO>()
                            .eq(WmsWarehouseDO::getId, warehouseId)
                            .set(WmsWarehouseDO::getUsedCap, wmsWarehouseDO.getUsedCap() + cap)
            );
        }

        if (wmsWarehouseDO.getMaxCap() != -1 && cap != -1) {
            if (wmsWarehouseDO.getMaxCap() - wmsWarehouseDO.getUsedCap() < cap) {
                throw new ServiceException(
                        "所属仓库容量不足,所属仓库剩余容量为" + (wmsWarehouseDO.getMaxCap() - wmsWarehouseDO.getUsedCap())
                );
            }
            wmsWarehouseMapper.update(
                    null,
                    new LambdaUpdateWrapper<WmsWarehouseDO>()
                            .eq(WmsWarehouseDO::getId, warehouseId)
                            .set(WmsWarehouseDO::getUsedCap, wmsWarehouseDO.getUsedCap() + cap)
            );
        }
    }

    public void decreaseUsedCap(long warehouseId, long cap) {
        WmsWarehouseDO wmsWarehouseDO = selectWmsWarehouseById(warehouseId);
        wmsWarehouseMapper.update(
                null,
                new LambdaUpdateWrapper<WmsWarehouseDO>()
                        .eq(WmsWarehouseDO::getId, warehouseId)
                        .set(WmsWarehouseDO::getUsedCap, wmsWarehouseDO.getUsedCap() - cap)
        );

    }

    public List<WmsWareStorageVO> getRelations() {
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        List<WmsWareStorageVO> list = wmsWarehouseMapper.getRelWareStorage(tenantId);
//        list.forEach(one->{
//            one.setStorageIdList(wmsWarehouseMapper.getRelationsStorage(one.getWarehouseId()));
//        });
        return list;
    }
}
